using Engine;
using Engine.Graphics;
using Game;
using GameEntitySystem;

namespace SCIENEW {
    public abstract class NormalBlock : IIEBlock {
        public virtual void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z) {
            generator.GenerateCubeVertices(BlocksManager.Blocks[BaseNormalBlock.Index], value, x, y, z, GetColor(value), geometry.GetGeometry(GetTexture(value)).OpaqueSubsetsByFace);
        }

        public virtual void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData) {
            BlocksManager.DrawCubeBlock(primitivesRenderer, value, new Vector3(size), ref matrix, GetColor(value), GetColor(value) * color, environmentData, GetTexture(value));
        }

        public virtual string GetDisplayName(SubsystemTerrain subsystemTerrain, int value) => string.Empty;

        public virtual string GetCategory(int value) => "Construction";

        public virtual int GetDisplayOrder(int value) => 318;

        public virtual Vector3 GetIconBlockOffset(int value, DrawBlockEnvironmentData environmentData) => Vector3.Zero;

        public virtual Vector3 GetIconViewOffset(int value, DrawBlockEnvironmentData environmentData) => Vector3.One;

        public virtual float GetIconViewScale(int value, DrawBlockEnvironmentData environmentData) => 1;

        public virtual float GetFirstPersonScale(int value) => 0.4f;

        public virtual Vector3 GetFirstPersonOffset(int value) => new Vector3(0.5f, -0.5f, -0.6f);

        public virtual Vector3 GetFirstPersonRotation(int value) => new Vector3(0, 40, 0);

        public virtual float GetInHandScale(int value) => 0.3f;

        public virtual Vector3 GetInHandOffset(int value) => new Vector3(0,0.12f,0);

        public virtual Vector3 GetInHandRotation(int value) => new Vector3(0, 0, 45);

        public virtual string GetCraftingId() => GetType().Name;

        public virtual bool IsCollidable_(int value) => true;

        public virtual bool IsPlaceable_(int value) => true;

        public virtual bool GetIsDiggingTransparent(int value) => false;

        public virtual bool IsPlacementTransparent_(int value) => false;

        public virtual bool IsInteractive(SubsystemTerrain subsystemTerrain, int value) => false;

        public virtual bool IsEditable_(int value) => false;

        public virtual bool IsNonDuplicable_(int value) => false;

        public virtual bool IsGatherable_(int value) => false;

        public virtual bool HasCollisionBehavior_(int value) => false;

        public virtual bool IsFluidBlocker_(int value) => true;

        public virtual bool IsTransparent_(int value) => false;

        public virtual int GetShadowStrength(int value) => 15;

        public virtual int GetEmittedLightAmount(int value) => 0;

        public virtual float GetObjectShadowStrength(int value) => 1;

        public virtual void GetDropValues(SubsystemTerrain subsystemTerrain, int oldValue, int newValue, int toolLevel, List<BlockDropValue> dropValues, out bool showDebris) {
            showDebris = true;
            dropValues.Add(new BlockDropValue { Value = oldValue, Count = 1 });
        }

        public virtual float GetRequiredToolLevel(int value) => 0;

        public virtual int GetMaxStacking(int value) => 40;

        public virtual float GetDensity(int value) => 10;

        public virtual float GetFuelHeatLevel(int value) => 0;

        public virtual float GetFuelFireDuration(int value) => 0;

        public virtual string GetSoundMaterialName(SubsystemTerrain subsystemTerrain, int value) => "Metal";

        public virtual float GetShovelPower(int value) => 1;

        public virtual float GetQuarryPower(int value) => 1;

        public virtual float GetHackPower(int value) => 1;

        public virtual float GetMeleePower(int value) => 1;

        public virtual float GetMeleeHitProbability(int value) => 0.66f;

        public virtual float GetProjectilePower(int value) => 2;

        public virtual int GetToolLevel(int value) => 1;

        public virtual int GetPlayerLevelRequired(int value) => 0;

        public virtual int GetDurability(int value) => -1;

        public virtual bool IsAimable_(int value) => false;

        public virtual bool IsStickable_(int value) => false;

        public virtual bool GetAlignToVelocity(int value) => false;

        public virtual float GetProjectileSpeed(int value) => 0;

        public virtual float GetProjectileDamping(int value) => 1;

        public virtual float GetProjectileStickProbability(int value) => 0;

        public virtual float GetHeat(int value) => 0;

        public virtual float GetFireDuration(int value) => 0;

        public virtual float GetExplosionResilience(int value) => 2000;

        public virtual float GetExplosionPressure(int value) => 0;

        public virtual bool GetExplosionIncendiary(int value) => false;

        public virtual BlockDigMethod GetBlockDigMethod(int value) => BlockDigMethod.Quarry;

        public virtual float GetDigResilience(int value) => 20;

        public virtual float GetProjectileResilience(int value) => 1;

        public virtual float GetNutritionalValue(int value) => 0;

        public virtual float GetSicknessProbability(int value) => 0;

        public virtual FoodType GetFoodType(int value) => FoodType.None;

        public virtual int GetRotPeriod(int value) => 0;

        public virtual int GetFaceTextureSlot(int face, int value) => 0;

        public virtual string GetDescription(int value) => string.Empty;

        public virtual int GetDamageDestructionValue(int value) => 1;

        public virtual bool Eat(ComponentVitalStats vitalStats, int value) => false;

        public virtual bool CanWear(int value) => false;

        public virtual int GetDamage(int value) => 1;

        public virtual int SetDamage(int value, int damage) => 1;

        public virtual bool ShouldAvoid(int value) => false;

        public virtual ClothingData GetClothingData(int value) => default;

        public virtual bool IsHeatBlocker(int value) => false;

        public virtual BlockPlacementData GetPlacementValue(SubsystemTerrain subsystemTerrain, ComponentMiner componentMiner, int value, TerrainRaycastResult raycastResult) => new BlockPlacementData{Value = value, CellFace = raycastResult.CellFace};

        public virtual BlockDebrisParticleSystem CreateDebrisParticleSystem(SubsystemTerrain subsystemTerrain, Vector3 position, int value, float strength) => default;

        public virtual BoundingBox[] GetCustomCollisionBoxes(SubsystemTerrain terrain, int value) => Block.m_defaultCollisionBoxes;

        public virtual bool IsFaceTransparent(SubsystemTerrain subsystemTerrain, int face, int value) => false;

        public virtual int GetTextureSlotCount(int value) => 16;

        public virtual bool ShouldGenerateFace(SubsystemTerrain subsystemTerrain, int face, int value, int neighborValue) => true;

        public virtual Texture2D GetTexture(int value) => IndustrialModLoader.BaseTexture;

        public virtual Color GetColor(int value) => Color.White;

        /// <summary>
        /// 程序性的自动创建配方，而不是读取.icr文件来创建
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public virtual CraftingRecipe[] GenerateProceduralRecipe(int value) => Array.Empty<CraftingRecipe>();

        public virtual NormalBlockBehavior[] GetBehaviors(Project project) => [];
    }
}